Python 24-Day Course - Day 24: Mini Project - FastAPI Todo API

Day 24: Mini Project - FastAPI Todo API

Installing FastAPI

pip install fastapi uvicorn

Project Structure

todo-api/
├── main.py          # API endpoints
├── models.py        # Data models
├── database.py      # DB connection
└── requirements.txt

Defining Data Models

# models.py
from pydantic import BaseModel
from typing import Optional

class TodoCreate(BaseModel):
    title: str
    description: Optional[str] = None

class TodoUpdate(BaseModel):
    title: Optional[str] = None
    description: Optional[str] = None
    completed: Optional[bool] = None

class TodoResponse(BaseModel):
    id: int
    title: str
    description: Optional[str]
    completed: bool

Implementing API Endpoints

# main.py
from fastapi import FastAPI, HTTPException
from models import TodoCreate, TodoUpdate, TodoResponse

app = FastAPI(title="Todo API")

todos: dict[int, dict] = {}
next_id = 1

@app.get("/todos", response_model=list[TodoResponse])
def get_todos():
    return list(todos.values())

@app.post("/todos", response_model=TodoResponse, status_code=201)
def create_todo(todo: TodoCreate):
    global next_id
    new_todo = {
        "id": next_id,
        "title": todo.title,
        "description": todo.description,
        "completed": False,
    }
    todos[next_id] = new_todo
    next_id += 1
    return new_todo

@app.get("/todos/{todo_id}", response_model=TodoResponse)
def get_todo(todo_id: int):
    if todo_id not in todos:
        raise HTTPException(status_code=404, detail="Todo not found")
    return todos[todo_id]

@app.patch("/todos/{todo_id}", response_model=TodoResponse)
def update_todo(todo_id: int, todo: TodoUpdate):
    if todo_id not in todos:
        raise HTTPException(status_code=404, detail="Todo not found")
    stored = todos[todo_id]
    update_data = todo.model_dump(exclude_unset=True)
    stored.update(update_data)
    return stored

@app.delete("/todos/{todo_id}", status_code=204)
def delete_todo(todo_id: int):
    if todo_id not in todos:
        raise HTTPException(status_code=404, detail="Todo not found")
    del todos[todo_id]

Running the Server and API Docs

uvicorn main:app --reload

# View auto-generated API docs in the browser
# http://127.0.0.1:8000/docs   (Swagger UI)
# http://127.0.0.1:8000/redoc  (ReDoc)

API Test Reference

MethodPathDescription
GET/todosList all todos
POST/todosCreate a new todo
GET/todos/{id}Get a single todo
PATCH/todos/{id}Update a todo
DELETE/todos/{id}Delete a todo

Today’s Exercises

  1. Integrate an SQLite database so data persists across server restarts.
  2. Add a priority field (high, medium, low) to todos and implement a filtering API.
  3. Write tests for all endpoints using pytest and TestClient.

Was this article helpful?